<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Strict//EN">
<html>

<head>
<meta http-equiv="Content-Language" content="en-us">
<title>Remote API modus operandi</title>
<link rel="stylesheet" type="text/css" href="../style.css">
</head>

<body>

<div align="center">
<table class=allEncompassingTable >
 <tr>
  <td >
<p><a href="../index.html" TARGET="_top"><img src="images/homeImg.png"></a></p>



<h1>Remote API modus operandi</h1>

<p class=warningBox>The remote API, or <em>legacy remote API</em>, should not be mixed-up with the <a href="b0RemoteApiOverview.htm">B&Oslash;-based remote API</a>, which is a newer version of the remote API that is more flexible, easier to use and most importantly, much simpler to extend.</p>

<p>A remote API function is called in a similar fashion as a <a href="apiOverview.htm">regular API</a> function, however with 2 major differences:</p>
<li>most remote API functions return a similar value: a <a href="remoteApiConstants.htm#returnCodes">return code</a>. Always remember that the return code is bit-coded (so you will have to test the individual bits in order to correctly interpret it).</li>
<li>most remote API functions require two additional argument:  <a href="remoteApiConstants.htm#operationModes">the operation mode</a>, and the clientID (identifier returned by the <a href="remoteApiFunctions.htm#simxStart">simxStart</a> function)</li>

<p>
The need for an <a href="remoteApiConstants.htm#operationModes">operation mode</a> and a specific <a href="remoteApiConstants.htm#functionErrorCodes">return code</a> comes from the fact that the remote API function has to travel via socket communication to the server (CoppeliaSim), execute a task, then return to the caller (the client). A naive (or <em>regular</em>) approach would be to have the client send a request, and wait until the server processed the request and replied: in most situations this would take too much time and the lag would penalize the client application. Instead, the remote API lets the user chose the type of operation mode and the way simulation advances by providing four main mechanisms to execute function calls or to control the simulation progress:</p>

<li><strong><a href="#blocking">Blocking function calls</a></strong></li>
<li><strong><a href="#nonBlocking">Non-blocking function calls</a></strong></li>
<li><strong><a href="#streaming">Data streaming</a></strong></li>
<li><strong><a href="#synchronous">Synchronous operation</a></strong></li>
<br>
<br>

<p><a name="blocking" id="blocking"></a><strong>Blocking function calls</strong>: a blocking function call is the naive or regular approach, and meant for situations where we cannot afford not to wait for a reply from the server, like in following situation:</p>

<pre class=lightPurpleBox>
// Following function (<strong>blocking</strong> mode) will retrieve an object handle:
if (simxGetObjectHandle(clientID,"myJoint",&jointHandle,simx_opmode_blocking)==simx_return_ok) 
{
    // here we have the joint handle in variable <em>jointHandle</em>!    
}</pre>

<p>Following diagram illustrates a blocking function call:</p>
<p align=center><img src="images/remoteApiBlocking.jpg"></p>
<p class=imageLabel>[Blocking function calls]</p>
<br>


<p><a name="nonBlocking" id="nonBlocking"></a><strong>Non-blocking function calls</strong>: a non-blocking function call is meant for situations when we simply want to send data to CoppeliaSim without the need for a reply, like in following situation:</p>

<pre class=lightPurpleBox>
// Following function (<strong>non-blocking</strong> mode) will set the position of a joint:
simxSetJointPosition(clientID,jointHandle,jointPosition,simx_opmode_oneshot); 
</pre>

<p>Following diagram illustrates non-blocking function calls:</p>
<p align=center><img src="images/remoteApiNonBlocking.jpg"></p>
<p class=imageLabel>[Non-blocking function calls]</p>
<br>

<p>In some situations, it is important to be able to send various data within a same message, in order to have that data also applied at the same time on the server side (e.g. we want the 3 joints of a robot to be applied to its CoppeliaSim model in the exact same time, i.e. in the same simulation step). In that case, the user can temporarily halt the communication thread in order to achieve this, as shown in following example: </p>

<pre class=lightPurpleBox>
simxPauseCommunication(clientID,1);
simxSetJointPosition(clientID,joint1Handle,joint1Value,simx_opmode_oneshot);
simxSetJointPosition(clientID,joint2Handle,joint2Value,simx_opmode_oneshot);
simxSetJointPosition(clientID,joint3Handle,joint3Value,simx_opmode_oneshot);
simxPauseCommunication(clientID,0);

// Above's 3 joints will be received and set on the CoppeliaSim side at the same time</pre>

<p>Following diagram illustrates the effect of temporarily halting the communication thread:</p>
<p align=center><img src="images/remoteApiCommPaused.jpg"></p>
<p class=imageLabel>[Temporarily pausing the communication thread]</p>
<br>




<p><a name="streaming" id="streaming"></a><strong>Data streaming</strong>: the server can anticipate what type of data the client requires. For that to happen, the client has to signal this desire to the server with a &quot;streaming&quot; or &quot;continuous&quot; operation mode flag (i.e. the function is stored on the server side, executed and sent on a regular time basis, without the need of a request from the client). This can be seen as a command/message subscription from the client to the server, where the server will be streaming the data to the client. Such a streaming operation request and reading of streamed data could look like this on the client side:
 </p>

<pre class=lightPurpleBoxTab>
// Streaming operation request (subscription) (function returns immediately (<strong>non-blocking</strong>)):
simxGetJointPosition(clientID,jointHandle,&jointPosition,simx_opmode_streaming);

// The control loop:
while (simxGetConnectionId(clientID)!=-1) // while we are connected to the server..
{ 
    // Fetch the newest joint value from the inbox (func. returns immediately (<strong>non-blocking</strong>)):
    if (simxGetJointPosition(clientID,jointHandle,&jointPosition,simx_opmode_buffer)==simx_return_ok) 
    { 
        // here we have the newest joint position in variable <em>jointPosition</em>!    
    }
    else
    {
        // once you have enabled data streaming, it will take a few ms until the first value has arrived. So if
        // we landed in this code section, this does not always mean we have an error!!!
    }
}

// Streaming operation is enabled/disabled individually for each command and
// object(s) the command applies to. In above case, only the joint position of
// the joint with handle <em>jointHandle</em> will be streamed.

// Before disconnecting from CoppeliaSim, make sure to disable the streamings you previously enabled:
simxGetJointPosition(clientID,jointHandle,&jointPosition,simx_opmode_discontinue);
simxGetPingTime(clientID,&pingTime); // needed to insure that above reaches CoppeliaSim before disconnection</pre>

<p>Following diagram illustrates data streaming:</p>
<p align=center><img src="images/remoteApiDataStreaming.jpg"></p>
<p class=imageLabel>[Data streaming]</p>
<br>

<p>Once you are done streaming the data, the remote API client should always inform the server (i.e. CoppeliaSim) to stop streaming that data, otherwise the server will continue to stream unnecessary data and eventually slow down. Use the <em>simx_opmode_discontinue</em> operation mode for that.</p>
<br>



<p><a name="synchronous" id="synchronous"></a><strong>Synchronous operation</strong>: from above function calls you might have noticed that a simulation will advance or progress without taking into account the progress of the remote API client. Remote API function calls will be executed asynchronously by default. There are however situations where the remote API client needs to be synchronized with the simulation progress, by controlling the simulation advance from the remote API client side. This can be achieved by using the remote API synchronous mode. The remote API server service needs in that case to be pre-enabled for synchronous operation (this can be achieved via the <a href="remoteApiServerSide.htm#simRemoteApi.start">simRemoteApi.start</a> function, or via the <a href="remoteApiServerSide.htm#continuousRemoteApiService">continuous remote API server service configuration file <em>remoteApiConnections.txt</em></a>). Following is an example of the synchronous mode:</p>

<pre class=lightPurpleBox>
simxSynchronous(clientID,true); // Enable the synchronous mode (<strong>Blocking</strong> function call)
simxStartSimulation(clientID,simx_opmode_oneshot);

// The first simulation step waits for a trigger before being executed

simxSynchronousTrigger(clientID); // Trigger next simulation step (<strong>Blocking</strong> function call)

// The first simulation step is now being executed

simxSynchronousTrigger(clientID); // Trigger next simulation step (<strong>Blocking</strong> function call)

// The second simulation step is now being executed

...</pre>

<p>Following diagram illustrates the synchronous mode:</p>
<p align=center><img src="images/remoteApiSynchronous.jpg"></p>
<p class=imageLabel>[Synchronous mode]</p>
<br>



<p><a name="synchronousDataUpdate" id="synchronousDataUpdate"></a>When calling simxSynchronousTrigger, the next simulation step will start computing. This doesn't mean that when the function call returns, the next simulation step will have finished computing.  For that reason you have to make sure to read the correct data. If no special measure is taken, you might read data from previous simulation step, or from current simulation step, as illustrated in following diagram:</p>

<p align=center><img src="images/remoteApiSynchronousUpdate1.jpg"></p>
<p class=imageLabel>[Synchronous mode, uncertain data update]</p>
<br>





<p>You have several possibilities to overcome above problematic situation. The simplest is to call a function in a blocking fashion directly after calling simxSynchronousTrigger:</p>

<pre class=lightPurpleBox>
simxSynchronous(clientID,true); // Enable the synchronous mode (<strong>Blocking</strong> function call)
simxStartSimulation(clientID,simx_opmode_oneshot);

// The first simulation step waits for a trigger before being executed

simxSynchronousTrigger(clientID); // Trigger next simulation step (<strong>Blocking</strong> function call)

// The first simulation step is now being executed

simxGetPingTime(clientID); // After this call, the first simulation step is finished (<strong>Blocking</strong> function call)

// Now we can safely read all streamed values</pre>

<p>Following diagram illustrates above procedure:</p>
<p align=center><img src="images/remoteApiSynchronousUpdate2.jpg"></p>
<p class=imageLabel>[Synchronous mode, correct data update]</p>
<br>


<p>When you have several remote API clients that each need to send their trigger for next simulation step to start, then you should place following code inside of a <a href="childScripts.htm#nonThreaded">non-threaded child script</a> in your scene:</p>

<pre class=lightRedBox>
function sysCall_init()
   iteration=1
end

function sysCall_sensing()
   simSetIntegerSignal('iteration',iteration)
   iteration=iteration+1
end

function sysCall_cleanup()
   simClearIntegerSignal('iteration')
end</pre>

<p>and following code in each one of your remote API clients:</p>

<pre class=lightPurpleBox>
// enable the synchronous mode on the client:
simxSynchronous(clientID,1);

// start the simulation:
simxStartSimulation(clientID,simx_opmode_blocking);

// enable streaming of a value:
int anyValue;
simxGetIntegerSignal(clientID,&quot;anyValue&quot;,&amp;anyValue,simx_opmode_streaming);

// enable streaming of the iteration counter:
int iteration1;
simxGetIntegerSignal(clientID,&quot;iteration&quot;,&amp;iteration,simx_opmode_streaming);

// Now step a few times:
for (int i=0;i&lt;30;i++)
{
    int res=simxGetIntegerSignal(clientID,&quot;iteration&quot;,&amp;iteration1,simx_opmode_buffer);
    if (res!=simx_return_ok)
        iteration1=-1;
    simxSynchronousTrigger(clientID);
    int iteration2=iteration1;
    while (iteration2==iteration1)
    { // wait until the iteration counter has changed
        res=simxGetIntegerSignal(clientID,&quot;iteration&quot;,&amp;iteration2,simx_opmode_buffer);
        if (res!=simx_return_ok)
            iteration2=-1;
    }

    // Now fetch other values:
    simxGetIntegerSignal(clientID,&quot;anyValue&quot;,&amp;anyValue,simx_opmode_buffer);
    printf(&quot;Streamed value: %i\n&quot;,anyValue) // this is the freshest value
}</pre>


<p>In above code just make sure that the last streaming command that you enabled is for signal <em>iteration</em>, otherwise <em>iteration</em> will not be the last updated value.</p>







<br>
<br>


<p><a name="serverSideCommandHandling" id="serverSideCommandHandling"></a>Following diagram illustrates how incoming remote API commands are handled on the server side (i.e. on the CoppeliaSim remote API plugin side):</p>

<p align=center><img src="images/remoteApi2.jpg"></p>
<p class=imageLabel>[Remote API command handling, server side]</p>
<br>
<br>



<table class=subsectionTable><tr class=subsectionTd><td class=subsectionTd>
<a name="additionalDetails"></a>Additional details
</td></tr></table> 


<p>
On the client side (i.e. your application), at least 2 threads will be running: the main thread (the one from which you will be calling remote API functions), and the communication thread (the one that will be handling data transfers behind the scenes). There can be as many communication threads (i.e. communication lines) as needed on the client side: make sure to call <a href="remoteApiFunctions.htm#simxStart">simxStart</a> for each one of them. The server side, which is implemented with a <a href="plugins.htm">CoppeliaSim plugin</a>, operates in a similar way. Following figure illustrates the remote API modus operandi: </p>

<p align=center><img src="images/remoteApi1.jpg"></p>
<p class=imageLabel>[Remote API functionality overview]</p>
<br>




<p><a name="operationModes" id="operationModes"></a>
Following describes the various supported <a href="remoteApiConstants.htm#operationModes">modes of operations</a>: </p>


<li><strong>simx_opmode_oneshot</strong>: non-blocking mode. A command is sent to the server for execution (1)-(b)-(3). A reply to a same command, but previously executed, is returned from a local buffer, if available (i)-(2). The function doesn't wait for a reply from the server (7)-(i).  On the server side, the command is stored temporarily (4)-(d), executed  once (d)-(9)-(g) and a reply sent back (g)-(6). This mode is often used with &quot;set-functions&quot; (e.g. simxSetJointPosition), where the user doesn't care about the return value.</li>

<li><strong>simx_opmode_blocking</strong>: blocking mode. A command is sent to the server for execution (1)-(b)-(3), and the function waits for the reply from the server (7)-(i)-(2). The received reply will then be erased from the inbox buffer (i), which doesn't happen with the other operation modes. On the server side, the command is stored temporarily (4)-(d), executed  once (d)-(9)-(g) and a reply sent back (g)-(6). This mode is often used with &quot;get-functions&quot; (e.g. simxGetObjectHandle), where the user requires a reply to the sent command.</li>

<li><strong>simx_opmode_streaming</strong>: non-blocking mode. A command is sent to the server for execution (1)-(b)-(3).  A reply to a same command, but previously executed, is returned from a local buffer, if available (i)-(2). The function doesn't wait for a reply from the server (7)-(i). Similar to simx_opmode_oneshot, but with the difference that the command will be stored on the server side (4)-(e),  continuously executed (e)-(9)-(g), and continuously sent back to the client (g)-(6). This mode is often used with &quot;get-functions&quot; (e.g. simxGetJointPosition), where the user requires a specific value constantly.</li>

<li><strong>simx_opmode_oneshot_split</strong> (not recommended): non-blocking mode. A command is sent gradually (in small data chunks) to the server for execution (1)-(a)-(3). A reply to a same command, but previously executed, is returned from a local buffer, if available (i)-(2). The function doesn't wait for a reply from the server (7)-(h)-(i). When the command was fully sent, it is removed from (a). On the server side, the command chunks are remporarily stored (4)-(c) and when the command was fully received, the command will be executed once (5)-(d)-(9)-(f) and a reply gradually sent back to the client (f)-(6). The client receives the reply in small chunks (7)-(h) and when the reply is complete, it is stored in the local buffer (8)-(i).  This mode is often used with &quot;set-functions&quot; associated with large amounts of data (e.g. simxSetVisionSensorImage), in order not to overload the communication network.</li>

<li><strong>simx_opmode_streaming_split </strong>(not recommended): non-blocking mode. A command is sent gradually (in small data chunks) to the server for execution (1)-(a)-(3).  A reply to a same command, but previously executed, is returned from a local buffer, if available (i)-(2). The function doesn't wait for a reply from the server (7)-(h)-(i). When the command was fully sent, it is removed from (a). On the server side, the command chunks are remporarily stored (4)-(c) and when the command was fully received (5)-(e), the command will be executed continuously (e)-(9)-(f) and a reply gradually sent back to the client (f)-(6). The client receives the reply in small chunks (7)-(h) and when the reply is complete, it is stored in the local buffer (8)-(i).  This mode is often used with &quot;get-functions&quot; associated with large amounts of data (e.g. simxGetVisionSensorImage), where the user requires data constantly without overloading the communication network.</li>

<li><strong>simx_opmode_discontinue</strong>: non-blocking mode. A command is sent to the server (1)-(b)-(3). A reply to a same command, but previously executed, is returned from a local buffer, if available (i)-(2). The function doesn't wait for a reply from the server (7)-(i).  On the server side, the command simply clears a similar command that is located in (e). A reply is sent to the client (6)-(7) that will also clear a similar reply located in (i). This mode is used to release some memory in (i) (similar to simx_opmode_remove), or to interrupt streaming commands (i.e. by removing them from (e)).</li>

<li><strong>simx_opmode_buffer</strong>: non-blocking mode. No command is sent to the server, but just a  reply to a same command, previously executed, is returned from a local buffer, if available (i)-(2). This mode is often used in conjunction with the simx_opmode_streaming or simx_opmode_streaming_split operation mode: first, a constant command execution is started with a streaming command, then only command replies fetched.</li>

<li><strong>simx_opmode_remove</strong>: non-blocking mode. No command is sent to the server, but just a  reply to a same command, previously executed, is cleared from the local buffer, if present (i). The function doesn't return any values, except for a return code. This mode can be used to release some memory on the client side, but is rarely necessary.</li>

<br>
<br>
<h3 class=recommendedTopics>Recommended topics</h3>
<li><a href="legacyRemoteApiOverview.htm">Remote API overview</a></li>
<li><a href="remoteApiExtension.htm">Extending the remote API</a></li>
<br>
<br>
 </tr>
 <tr>
   <td > 
 </tr>
</table> 
</div>  
  
  
</body>

</html>
